using System;
using System.IO;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;

using Pegasus.Runtime.Serialization.Formatters.Xml;

namespace Pegasus.Runtime.Serialization
{
	/// <summary>
	/// Helper class to quickly serialize/deserialze objects.
	/// </summary>
	public static class SerializationHelper
	{
		/// <summary>
		/// Serializes an Object to XML using the Pegasus XML formmater.
		/// </summary>
		/// <param name="objectToSerialize">The object to serialize.</param>
		/// <returns></returns>
		public static string ObjectToXml( object objectToSerialize )
		{
			using( MemoryStream memStream = new MemoryStream() )
			{
				XmlFormatter2 formatter = new XmlFormatter2();
                formatter.XmlSettings.OmitXmlDeclaration = true;
				formatter.Serialize( memStream, objectToSerialize );
				memStream.Flush();

				return UTF8Encoding.UTF8.GetString( memStream.GetBuffer(), 0, (int) memStream.Position );
			}
		}

		/// <summary>
		/// Deserializes XML to an Object using the Pegasus XML Formatter.
		/// </summary>
		/// <param name="xml">The XML.</param>
		/// <returns></returns>
		public static object XmlToObject( string xml )
		{
			if( !string.IsNullOrEmpty( xml ) )
			{
                using( MemoryStream memStream = new MemoryStream( UTF8Encoding.UTF8.GetBytes( xml ) ) )
				{
					return XmlToObject( memStream );
				}
			}

			return null;
		}

		/// <summary>
		/// Deserializes XML that is in the memory stream to an Object using the Pegasus XML Formatter.
		/// </summary>
		/// <param name="stream">The stream.</param>
		/// <returns></returns>
		public static object XmlToObject( Stream stream )
		{
			if( stream != null && stream.Length > 0 )
			{
				XmlFormatter2 formatter = new XmlFormatter2();
				formatter.XmlSettings.OmitXmlDeclaration = true;
				return formatter.Deserialize( stream );
			}

			return null;
		}

		/// <summary>
		/// Serializes an Object to Blob using the binary formatter.
		/// </summary>
		/// <param name="objectToSerialize">The object to serialize.</param>
		/// <returns></returns>
		public static byte[] ObjectToBlob( object objectToSerialize )
		{
			using( MemoryStream memStream = new MemoryStream() )
			{
				BinaryFormatter formatter = new BinaryFormatter();
				formatter.Serialize( memStream, objectToSerialize );
				memStream.Flush();
				
				return memStream.ToArray();
			}
		}

		/// <summary>
		/// Deserialize a Blob to an Object using the binary formatter.
		/// </summary>
		/// <param name="blob">The BLOB.</param>
		/// <returns></returns>
		public static object BlobToObject( byte[] blob )
		{
			if( blob != null && blob.Length > 0 )
			{
				using( MemoryStream memStream = new MemoryStream( blob ) )
				{
					return BlobToObject( memStream );
				}
			}

			return null;
		}

		/// <summary>
		/// Deserialize a Blob that is in the stream to an Object using the binary formatter.
		/// </summary>
		/// <param name="stream">The stream.</param>
		/// <returns></returns>
		public static object BlobToObject( Stream stream )
		{
			if( stream != null && stream.Length > 0 )
			{
				BinaryFormatter formatter = new BinaryFormatter();
				return formatter.Deserialize( stream );
			}

			return null;
		}
	}
}
